int INDICATOR_HIGH = 0;
int INDICATOR_LOW = 1;
int INDICATOR_EMA5 = 2;
int INDICATOR_EMA50 = 3;
int INDICATOR_MACD = 4;
int INDICATOR_MACD_Signal = 5;
int INDICATOR_MACD_Histogram = 6;
int INDICATOR_ADX = 7;
int INDICATOR_Parabolic_SAR = 8;
int INDICATOR_RSI = 9;
int INDICATOR_WilliamsR = 10;
int INDICATOR_ROC = 11;
int INDICATOR_ATR = 12;
int INDICATOR_Bollinger_Upper = 13;
int INDICATOR_Bollinger_Middle = 14;
int INDICATOR_Bollinger_Lower = 15;
int INDICATOR_STDEV = 16;
int INDICATOR_TRIX = 17;
int INDICATOR_CCI = 18;
int INDICATOR_STOCHASTIC = 19;
int INDICATOR_TOTAL = 20;
 
int ACTIVE_SIGNAL_NONE = 0;
int ACTIVE_SIGNAL_BUY = 1;
int ACTIVE_SIGNAL_SELL = 2;

int MAX_ARRAY_LEN = 100;
double arrayData[20][100];
int i;

int signalType = 0;
int signalTypePrev = 0;

int globalIterationCounter;
bool execTestCase = false;

double LOT = 100000.0;
int type = 0;
int typePrev = 0;
int ticket = -1;

double stopLoss = 0.0013;
double takeProfit = 0.0044;
double invest;

string outputFile = "mql_validation_mql_indicator.csv";

void start(){
 Print("counter", globalIterationCounter);

 globalIterationCounter++;

 shiftArray(INDICATOR_HIGH,Ask);
 shiftArray(INDICATOR_LOW,Bid);

 int handle;
 
 if(globalIterationCounter == 60 && !execTestCase){
  shiftArray(INDICATOR_EMA5,myEMA(INDICATOR_LOW,arrayData[INDICATOR_EMA5,0],5,true));
  shiftArray(INDICATOR_EMA50,myEMA(INDICATOR_LOW,arrayData[INDICATOR_EMA5,0],50,true));
  
  handle = FileOpen(outputFile, FILE_CSV|FILE_WRITE|FILE_READ, ';');
  if(handle>0){
   FileSeek(handle, 0, SEEK_END);
   FileWrite(handle, "TIME","BID","ASK","LOW","HIGH","EMA5","EMA50","MACD","MACD_Signal","MACD_Histogram","ADX","Parabolic_SAR","RSI","WilliamsR","ROC","ATR","Bollinger_Upper","Bollinger_Middle","Bollinger_Lower","STDEV","TRIX","CCI","StochasticOszilator");
   FileClose(handle);  
  }
  
 }else if(globalIterationCounter > 60 && !execTestCase){
  shiftArray(INDICATOR_EMA5,myEMA(INDICATOR_LOW,arrayData[INDICATOR_EMA5,0],5,false));
  shiftArray(INDICATOR_EMA50,myEMA(INDICATOR_LOW,arrayData[INDICATOR_EMA5,0],50,false));
  shiftArray(INDICATOR_MACD,myMACD(INDICATOR_HIGH, 12, 26));
  shiftArray(INDICATOR_MACD_Signal,myMACDSignal(INDICATOR_HIGH, 12, 26,9));
  shiftArray(INDICATOR_MACD_Histogram,myMACDHistogram(INDICATOR_HIGH, 12, 26,9));
  shiftArray(INDICATOR_ADX,myADX(INDICATOR_HIGH, INDICATOR_LOW, INDICATOR_LOW,14));
  shiftArray(INDICATOR_Parabolic_SAR,myParabolicSAR(INDICATOR_HIGH,INDICATOR_LOW,0.02,0.2,0.02));
  shiftArray(INDICATOR_RSI,myRSI(INDICATOR_HIGH, 14));
  shiftArray(INDICATOR_WilliamsR,myWilliamsR(INDICATOR_HIGH,INDICATOR_LOW,INDICATOR_LOW, 14));
  shiftArray(INDICATOR_ROC,myROC(INDICATOR_HIGH, 12));
  shiftArray(INDICATOR_ATR,myATR(INDICATOR_HIGH,INDICATOR_LOW,INDICATOR_LOW, 14));
  shiftArray(INDICATOR_Bollinger_Upper,myBollingerUpper(INDICATOR_HIGH, 20));
  shiftArray(INDICATOR_Bollinger_Middle,myBollingerMiddle(INDICATOR_HIGH, 20));
  shiftArray(INDICATOR_Bollinger_Lower,myBollingerLower(INDICATOR_HIGH, 20));
  shiftArray(INDICATOR_STDEV,mySTDEV(INDICATOR_HIGH, 10));
  shiftArray(INDICATOR_TRIX,myTRIX(INDICATOR_HIGH, 15));
  shiftArray(INDICATOR_CCI,myCCI(INDICATOR_HIGH,INDICATOR_LOW,INDICATOR_LOW, 20,0.015));
  shiftArray(INDICATOR_STOCHASTIC,myStochastic(INDICATOR_HIGH,INDICATOR_LOW,INDICATOR_LOW, 14));

  handle = FileOpen(outputFile, FILE_CSV|FILE_WRITE|FILE_READ, ';');
  if(handle>0){
   FileSeek(handle, 0, SEEK_END);
   FileWrite(handle, globalIterationCounter,Bid, Ask,Bid, Ask,arrayData[INDICATOR_EMA5,0],arrayData[INDICATOR_EMA50,0],arrayData[INDICATOR_MACD,0],arrayData[INDICATOR_MACD_Signal,0],arrayData[INDICATOR_MACD_Histogram,0],arrayData[INDICATOR_ADX,0],arrayData[INDICATOR_Parabolic_SAR,0],arrayData[INDICATOR_RSI,0],arrayData[INDICATOR_WilliamsR,0],arrayData[INDICATOR_ROC,0],arrayData[INDICATOR_ATR,0],arrayData[INDICATOR_Bollinger_Upper,0],arrayData[INDICATOR_Bollinger_Middle,0],arrayData[INDICATOR_Bollinger_Lower,0],arrayData[INDICATOR_STDEV,0],arrayData[INDICATOR_TRIX,0],arrayData[INDICATOR_CCI,0],arrayData[INDICATOR_STOCHASTIC,0]);
   FileClose(handle);  
  }
 }
}

double money2Lot(double money){
 return (NormalizeDouble((money/LOT),2));
}

void shiftArray(int indicator,double value) {
 for(i=MAX_ARRAY_LEN-2;i>=0;i--){
  arrayData[indicator,i+1] = arrayData[indicator,i];
 }
 arrayData[indicator,0] = value;
}

bool downTrend(double valueA,double valueB,double valueC){
 bool result = false;
 if(valueA < valueB && valueB < valueC){
  result = true;
 }
 return (result);
}

bool upTrend(double valueA,double valueB,double valueC){
 bool result = false;
 if(valueA > valueB && valueB > valueC){
  result = true;
 }
 return (result);
}

bool larger(double valueA,double valueB){
 bool result = false;
 if(valueA > valueB){
  result = true;
 }
 return (result);
}

bool largerEqual(double valueA,double valueB){
 bool result = false;
 if(valueA >= valueB){
  result = true;
 }
 return (result);
}

bool less(double valueA,double valueB){
 bool result = false;
 if(valueA < valueB){
  result = true;
 }
 return (result);
}

bool lessEqual(double valueA,double valueB){
 bool result = false;
 if(valueA <= valueB){
  result = true;
 }
 return (result);
}


double mySMA(int indicator,double periodLen){
 double sum = 0.0;
 for(i=0;i<periodLen;i++){
  sum += arrayData[indicator,i];
 }
 return (sum / periodLen);
}

double myEMA(int indicator,double prevEMA,int periodLen,bool doInit){
 double result;
 if(doInit){
  result = mySMA(indicator, periodLen);
 }else{
  result = ((arrayData[indicator,0] - prevEMA) * (2.0 / (periodLen + 1.0))) + prevEMA;
 }
 return (result);
}

bool initMyTRIX = false;
double trixFirstPrevEMA;
double trixDoublePrevEMA;
double trixTriplePrevEMA;
double trix;
double myTRIX(int indicator, double periodLen){
 double fac = 2.0 / (periodLen + 1.0);
 double trixFirstCurrentEMA = 0.0;
 double trixDoubleCurrentEMA = 0.0;
 double trixTripleCurrentEMA = 0.0;
 
 if(!initMyTRIX){
  initMyTRIX = true;

  for (i = (periodLen * 3)-2; i > (periodLen * 2)-2; i--) {
   trixFirstPrevEMA += arrayData[indicator,i];
  }
  trixFirstPrevEMA /= periodLen;
  
  for (i = (periodLen * 2)-2; i > periodLen-1; i--) {
   trixFirstCurrentEMA = ((arrayData[indicator,i] - trixFirstPrevEMA) * fac) + trixFirstPrevEMA;
   trixDoublePrevEMA += trixFirstPrevEMA;
   trixFirstPrevEMA = trixFirstCurrentEMA;
  }
  trixDoublePrevEMA += trixFirstPrevEMA;
  trixDoublePrevEMA /= periodLen;

  for (i = periodLen - 1; i > 0; i--) {
   trixFirstCurrentEMA = ((arrayData[indicator,i] - trixFirstPrevEMA) * fac) + trixFirstPrevEMA;
   trixDoubleCurrentEMA = ((trixFirstCurrentEMA - trixDoublePrevEMA) * fac) + trixDoublePrevEMA;
   trixFirstPrevEMA = trixFirstCurrentEMA;
   trixTriplePrevEMA += trixDoublePrevEMA;
   trixDoublePrevEMA = trixDoubleCurrentEMA;
  }

  trixTriplePrevEMA += trixDoublePrevEMA;
  trixTriplePrevEMA /= periodLen;
 }

 trixFirstCurrentEMA = ((arrayData[indicator,0] - trixFirstPrevEMA) * fac) + trixFirstPrevEMA;
 trixDoubleCurrentEMA = ((trixFirstCurrentEMA - trixDoublePrevEMA) * fac) + trixDoublePrevEMA;
 trixTripleCurrentEMA = ((trixDoubleCurrentEMA - trixTriplePrevEMA) * fac) + trixTriplePrevEMA;

 trix = ((trixTripleCurrentEMA - trixTriplePrevEMA) / trixTriplePrevEMA) * 100.0;
 trixFirstPrevEMA = trixFirstCurrentEMA;
 trixDoublePrevEMA = trixDoubleCurrentEMA;
 trixTriplePrevEMA = trixTripleCurrentEMA;

 return (trix);
}

double mySTDEV(int indicator,double periodLen){
 double sma = mySMA(indicator,periodLen);
 
 double sum = 0.0;
 for(i=0;i<periodLen;i++){
  sum += (arrayData[indicator,i]-sma)*(arrayData[indicator,i]-sma);
 }
 return (MathSqrt(sum / periodLen));
}

double myBollingerMiddle(int indicator,double periodLen){
 return (mySMA(indicator, periodLen));
}

double myBollingerUpper(int indicator,double periodLen) {
 return (mySMA(indicator, periodLen) + (2.0 * mySTDEV(indicator, periodLen)));
}

double myBollingerLower(int indicator,double periodLen) {
 return (mySMA(indicator, periodLen) - (2.0 * mySTDEV(indicator, periodLen)));
}

double myROC(int indicator, int periodLen){
 return (((arrayData[indicator,0]-arrayData[indicator,periodLen])/arrayData[indicator,periodLen])*100.0);
}

bool initMyRSI = false;
double rsiPrevGain;
double rsiPrevLoss;
double myRSI(int indicator, double periodLen) {
 double diff;
 if (!initMyRSI) {
  rsiPrevGain = 0.0;
  rsiPrevLoss = 0.0;

  for (i = 0; i < periodLen; i++) {
   diff = arrayData[indicator,i] - arrayData[indicator,i + 1];
   if (diff > 0.0) {
    rsiPrevGain += diff;
   } else {
    rsiPrevLoss += MathAbs(diff);
   }
  }

  rsiPrevGain /= periodLen;
  rsiPrevLoss /= periodLen;
  initMyRSI = true;
 } else {
  diff = arrayData[indicator,0] - arrayData[indicator,1];

  if (diff > 0.0) {
   rsiPrevGain = (rsiPrevGain * (periodLen - 1) + diff) / periodLen;
   rsiPrevLoss = (rsiPrevLoss * (periodLen - 1)) / periodLen;
  } else {
   rsiPrevGain = (rsiPrevGain * (periodLen - 1)) / periodLen;
   rsiPrevLoss = (rsiPrevLoss * (periodLen - 1) + MathAbs(diff)) / periodLen;
  }
 }
 return ((100.0 * rsiPrevGain) / (rsiPrevGain + rsiPrevLoss));
}

bool initMyADX = false;
double trueRangeN;
double dmPlusN;
double dmMinusN;
double adx;
double myADX(int indicatorHigh,int indicatorLow, int indicatorClose, double periodLen){
 double trueRange = 0.0;
 double dmPlus = 0.0;
 double dmMinus = 0.0;

 double diPlusN = 0.0;
 double diMinusN = 0.0;
 double diDiffN = 0.0;
 double diSumN = 0.0;
 double dx = 0.0;
 
 if (!initMyADX) {
  initMyADX = true;
  
  for (i = (periodLen - 1) * 2; i > periodLen - 2; i--) {
   trueRange = MathMax(arrayData[indicatorHigh,i] - arrayData[indicatorLow,i], MathMax( MathAbs(arrayData[indicatorHigh,i] - arrayData[indicatorClose,i + 1]), MathAbs(arrayData[indicatorLow,i] - arrayData[indicatorClose,i + 1])));
   if (arrayData[indicatorHigh,i] - arrayData[indicatorHigh,i + 1] > arrayData[indicatorLow,i + 1] - arrayData[indicatorLow,i]) {
    dmPlus = MathMax(arrayData[indicatorHigh,i] - arrayData[indicatorHigh,i + 1], 0.0);
   } else {
    dmPlus = 0.0;
   }

   if (arrayData[indicatorLow,i + 1] - arrayData[indicatorLow,i] > arrayData[indicatorHigh,i] - arrayData[indicatorHigh,i + 1]) {
    dmMinus = MathMax(arrayData[indicatorLow,i + 1] - arrayData[indicatorLow,i], 0.0);
   } else {
    dmMinus = 0.0;
   }

   trueRangeN += trueRange;
   dmPlusN += dmPlus;
   dmMinusN += dmMinus;
  }

  diPlusN = 100.0 * (dmPlusN / trueRangeN);
  diMinusN = 100.0 * (dmMinusN / trueRangeN);
  diDiffN = MathAbs(diPlusN - diMinusN);
  diSumN = diPlusN + diMinusN;
  dx = 100.0 * (diDiffN / diSumN);

  for (i = periodLen - 2; i >= 0; i--) {
   adx += dx;

   trueRange = MathMax(arrayData[indicatorHigh,i] - arrayData[indicatorLow,i], MathMax( MathAbs(arrayData[indicatorHigh,i] - arrayData[indicatorClose,i + 1]), MathAbs(arrayData[indicatorLow,i] - arrayData[indicatorClose,i + 1])));

   if (arrayData[indicatorHigh,i] - arrayData[indicatorHigh,i + 1] > arrayData[indicatorLow,i + 1] - arrayData[indicatorLow,i]) {
    dmPlus = MathMax(arrayData[indicatorHigh,i] - arrayData[indicatorHigh,i + 1], 0.0);
   } else {
    dmPlus = 0.0;
   }

   if (arrayData[indicatorLow,i + 1] - arrayData[indicatorLow,i] > arrayData[indicatorHigh,i] - arrayData[indicatorHigh,i + 1]) {
    dmMinus = MathMax(arrayData[indicatorLow,i + 1] - arrayData[indicatorLow,i], 0.0);
   } else {
    dmMinus = 0.0;
   }

   trueRangeN = trueRangeN - (trueRangeN / periodLen) + trueRange;
   dmPlusN = dmPlusN - (dmPlusN / periodLen) + dmPlus;
   dmMinusN = dmMinusN - (dmMinusN / periodLen) + dmMinus;

   diPlusN = 100.0 * (dmPlusN / trueRangeN);
   diMinusN = 100.0 * (dmMinusN / trueRangeN);
   diDiffN = MathAbs(diPlusN - diMinusN);
   diSumN = diPlusN + diMinusN;
   dx = 100.0 * (diDiffN / diSumN);
  }

  adx += dx;
  adx /= periodLen;
 } else {
  trueRange = MathMax(arrayData[indicatorHigh,0] - arrayData[indicatorLow,0], MathMax(MathAbs(arrayData[indicatorHigh,0] - arrayData[indicatorClose,1]), MathAbs(arrayData[indicatorLow,0] - arrayData[indicatorClose,1])));

  if (arrayData[indicatorHigh,0] - arrayData[indicatorHigh,1] > arrayData[indicatorLow,1] - arrayData[indicatorLow,0]) {
   dmPlus = MathMax(arrayData[indicatorHigh,0] - arrayData[indicatorHigh,1], 0.0);
  } else {
   dmPlus = 0.0;
  }

  if (arrayData[indicatorLow,1] - arrayData[indicatorLow,0] > arrayData[indicatorHigh,0] - arrayData[indicatorHigh,1]) {
   dmMinus = MathMax(arrayData[indicatorLow,1] - arrayData[indicatorLow,0], 0.0);
  } else {
   dmMinus = 0.0;
  }

  trueRangeN = trueRangeN - (trueRangeN / periodLen) + trueRange;
  dmPlusN = dmPlusN - (dmPlusN / periodLen) + dmPlus;
  dmMinusN = dmMinusN - (dmMinusN / periodLen) + dmMinus;

  diPlusN = 100.0 * (dmPlusN / trueRangeN);
  diMinusN = 100.0 * (dmMinusN / trueRangeN);
  diDiffN = MathAbs(diPlusN - diMinusN);
  diSumN = diPlusN + diMinusN;
  dx = 100.0 * (diDiffN / diSumN);
  adx = ((adx * (periodLen - 1)) + dx) / periodLen;
 }
 return (adx);
}

double myWilliamsR(int indicatorHigh, int indicatorLow, int indicatorClose, int periodLen) {
 double min = 65536.0;
 double max = -65536.0;

 for (i = 0; i < periodLen; i++) {
  max = MathMax(max, arrayData[indicatorHigh,i]);
  min = MathMin(min, arrayData[indicatorLow,i]);
 }

 return (((max - arrayData[indicatorClose,0]) / (max - min)) * (-100.0));
}

double myCCI(int indicatorHigh,int indicatorLow, int indicatorClose, double periodLen, double lambert){
 double typicalPrice = 0.0;
 double sum = 0.0;
 for (i = 0; i < periodLen; i++) {
  sum += (arrayData[indicatorHigh,i] + arrayData[indicatorLow,i] + arrayData[indicatorClose,i]) / 3.0;
 }
 sum /= periodLen;

 double deviation = 0.0;
 for (i = periodLen - 1; i >= 0; i--) {
  typicalPrice = (arrayData[indicatorHigh,i] + arrayData[indicatorLow,i] + arrayData[indicatorClose,i]) / 3.0;
  deviation += MathAbs(sum - typicalPrice);
 }
 deviation /= periodLen;
 return ((typicalPrice - sum) / (lambert * deviation));
}

bool initMyATR = false;
double atr;
double myATR(int indicatorHigh, int indicatorLow, int indicatorClose, int periodLen) {
 double norm = periodLen;
 i = periodLen - 1;
 double diffHL = (arrayData[indicatorHigh,i] - arrayData[indicatorLow,i]);
 double diffHC = 0.0;
 double diffLC = 0.0;
 double trueRange = MathMax(diffHL, MathMax(diffHC, diffLC));

 if (!initMyATR) {
  initMyATR = true;
  for (i = periodLen - 2; i >= 0; i--) {
   diffHL = arrayData[indicatorHigh,i] - arrayData[indicatorLow,i];
   diffHC = MathAbs(arrayData[indicatorHigh,i] - arrayData[indicatorClose,i + 1]);
   diffLC = MathAbs(arrayData[indicatorLow,i] - arrayData[indicatorClose,i + 1]);
   trueRange += MathMax(diffHL, MathMax(diffHC, diffLC));
  }

  atr = trueRange / norm;
 } else {
  diffHL = arrayData[indicatorHigh,0] - arrayData[indicatorLow,0];
  diffHC = MathAbs(arrayData[indicatorHigh,0] - arrayData[indicatorClose,1]);
  diffLC = MathAbs(arrayData[indicatorLow,0] - arrayData[indicatorClose,1]);
  trueRange = MathMax(diffHL, MathMax(diffHC, diffLC));
  atr = ((atr * (norm - 1)) + trueRange) / norm;
 }

 return (atr);
}

double myStochastic(int indicatorHigh, int indicatorLow, int indicatorClose, int periodLen) {
 double min = 65536.0;
 double max = -65536.0;

 for (i = 0; i < periodLen; i++) {
  max = MathMax(max, arrayData[indicatorHigh,i]);
  min = MathMin(min, arrayData[indicatorLow,i]);
 }

 return (((arrayData[indicatorClose,0] - min) / (max - min)) * 100.0);
}

bool initMyMACD = false;
double macdShortEMA;
double macdLongEMA;
double myMACD(int indicator, double periodLenShort,double periodLenLong) {
 double facShort = 2.0 / (periodLenShort + 1.0);
 double facLong = 2.0 / (periodLenLong + 1.0);

 if(!initMyMACD){
  initMyMACD = true;
  
  for (i = periodLenLong-1; i > periodLenLong-periodLenShort-1; i--) {
   macdShortEMA += arrayData[indicator,i];
   macdLongEMA += arrayData[indicator,i];
  }
  macdShortEMA /= periodLenShort;

  for (i = periodLenLong-periodLenShort-1; i > 0; i--) {
   macdLongEMA += arrayData[indicator,i];
   macdShortEMA = ((arrayData[indicator,i] - macdShortEMA) * facShort) + macdShortEMA;
  }

  macdLongEMA += arrayData[indicator,0];
  macdLongEMA /= periodLenLong;
 }else{
  macdLongEMA = ((arrayData[indicator,0] - macdLongEMA) * facLong) + macdLongEMA;
 }
 macdShortEMA = ((arrayData[indicator,0] - macdShortEMA) * facShort) + macdShortEMA;

 return (macdShortEMA-macdLongEMA);
}

bool initMyMACDSignal = false;
double macdSignalShortEMA;
double macdSignalLongEMA;
double macdSignal;
double myMACDSignal(int indicator, double periodLenShort,double periodLenLong,double periodSignalLen) {
 double facShort = 2.0 / (periodLenShort + 1.0);
 double facLong = 2.0 / (periodLenLong + 1.0);

 if(!initMyMACDSignal){
  initMyMACDSignal = true;
  
  for (i = periodLenLong-1+periodSignalLen-1; i > periodLenLong-periodLenShort-1+periodSignalLen-1; i--) {
   macdSignalShortEMA += arrayData[indicator,i];
   macdSignalLongEMA += arrayData[indicator,i];
  }
  macdSignalShortEMA /= periodLenShort;

  for (i = periodLenLong-periodLenShort-1+periodSignalLen-1; i > periodSignalLen-1; i--) {
   macdSignalLongEMA += arrayData[indicator,i];
   macdSignalShortEMA = ((arrayData[indicator,i] - macdSignalShortEMA) * facShort) + macdSignalShortEMA;
  }
  
  i = periodSignalLen-1;
  macdSignalLongEMA += arrayData[indicator,i];
  macdSignalLongEMA /= periodLenLong;
  
  for (i = periodSignalLen-1; i > 0; i--) {
   macdSignalShortEMA = ((arrayData[indicator,i] - macdSignalShortEMA) * facShort) + macdSignalShortEMA;
   macdSignal += macdSignalShortEMA-macdSignalLongEMA;
   macdSignalLongEMA = ((arrayData[indicator,i-1] - macdSignalLongEMA) * facLong) + macdSignalLongEMA;
  }
  macdSignalShortEMA = ((arrayData[indicator,i] - macdSignalShortEMA) * facShort) + macdSignalShortEMA;
  macdSignal += macdSignalShortEMA-macdSignalLongEMA;
  macdSignal /= periodSignalLen;
 }else{
  macdSignalLongEMA = ((arrayData[indicator,0] - macdSignalLongEMA) * facLong) + macdSignalLongEMA;
  macdSignalShortEMA = ((arrayData[indicator,0] - macdSignalShortEMA) * facShort) + macdSignalShortEMA;
  macdSignal = (macdSignal * (periodSignalLen - 1) + (macdSignalShortEMA - macdSignalLongEMA)) / periodSignalLen;
 }

 return (macdSignal);
}

bool initMyMACDHistogram = false;
double macdHistogramShortEMA;
double macdHistogramLongEMA;
double macdHistogram;
double myMACDHistogram(int indicator, double periodLenShort,double periodLenLong,double periodSignalLen) {
 double facShort = 2.0 / (periodLenShort + 1.0);
 double facLong = 2.0 / (periodLenLong + 1.0);

 if(!initMyMACDHistogram){
  initMyMACDHistogram = true;

  for (i = periodLenLong - 1 + periodSignalLen - 1; i > periodLenLong - periodLenShort - 1 + periodSignalLen - 1; i--) {
   macdHistogramShortEMA += arrayData[indicator,i];
   macdHistogramLongEMA += arrayData[indicator,i];
  }
  macdHistogramShortEMA /= periodLenShort;

  for (i = periodLenLong - periodLenShort - 1 + periodSignalLen - 1; i > periodSignalLen - 1; i--) {
   macdHistogramLongEMA += arrayData[indicator,i];
   macdHistogramShortEMA = ((arrayData[indicator,i] - macdHistogramShortEMA) * facShort) + macdHistogramShortEMA;
  }
  i = periodSignalLen-1;
  macdHistogramLongEMA += arrayData[indicator,i];
  macdHistogramLongEMA /= periodLenLong;
  
  for (i = periodSignalLen - 1; i > 0; i--) {
   macdHistogramShortEMA = ((arrayData[indicator,i] - macdHistogramShortEMA) * facShort) + macdHistogramShortEMA;
   macdHistogram += macdHistogramShortEMA - macdHistogramLongEMA;
   macdHistogramLongEMA = ((arrayData[indicator,i-1] - macdHistogramLongEMA) * facLong) + macdHistogramLongEMA;
  }
  macdHistogramShortEMA = ((arrayData[indicator,i] - macdHistogramShortEMA) * facShort) + macdHistogramShortEMA;
  macdHistogram += macdHistogramShortEMA - macdHistogramLongEMA;
  macdHistogram /= periodSignalLen;
 }else{
  macdHistogramLongEMA = ((arrayData[indicator,0] - macdHistogramLongEMA) * facLong) + macdHistogramLongEMA;
  macdHistogramShortEMA = ((arrayData[indicator,0] - macdHistogramShortEMA) * facShort) + macdHistogramShortEMA;
  macdHistogram = (macdHistogram * (periodSignalLen - 1) + (macdHistogramShortEMA - macdHistogramLongEMA)) / periodSignalLen;
 }

 return ((macdHistogramShortEMA - macdHistogramLongEMA) - macdHistogram);
}

bool initMyParabolicSAR = false;
bool longPosition;
double af;
double sar;
double maxHigh;
double minLow;
double myParabolicSAR(int indicatorHigh, int indicatorLow, double afStart, double afMax, double afDelta) {
 if (!initMyParabolicSAR) {
  initMyParabolicSAR = true;
  af = afStart;

  if (arrayData[indicatorHigh,1] < arrayData[indicatorHigh,0]) {
   longPosition = true;
   sar = MathMin(arrayData[indicatorLow,0], arrayData[indicatorLow,1]);
   maxHigh = MathMax(arrayData[indicatorHigh,0], arrayData[indicatorHigh,1]);
  } else {
   longPosition = false;
   sar = MathMax(arrayData[indicatorHigh,0], arrayData[indicatorHigh,1]);
   minLow = MathMin(arrayData[indicatorLow,0], arrayData[indicatorLow,1]);
  }
 } else {
  if (af < afMax) {
   if (longPosition && arrayData[indicatorHigh,0] > maxHigh) {
    maxHigh = arrayData[indicatorHigh,0];
    af += afDelta;
   } else if (!longPosition && arrayData[indicatorLow,0] < minLow) {
    minLow = arrayData[indicatorLow,0];
    af += afDelta;
   }
  }

  if (longPosition) {
   sar = af * (arrayData[indicatorHigh,0] - sar) + sar;
  } else {
   sar = af * (arrayData[indicatorLow,0] - sar) + sar;
  }

  double sart = 0.0;
  if (longPosition) {
   if (sar > arrayData[indicatorLow,0] /*|| sar > arrayData[indicatorLow,1]*/) {
    af = afStart;
    minLow = MathMin(arrayData[indicatorLow,0], arrayData[indicatorLow,1]);
    sart = MathMax(arrayData[indicatorHigh,0], arrayData[indicatorHigh,1]);
    sar = af * (arrayData[indicatorLow,0] - sart) + sart;
    longPosition = false;
   }
  } else {
   if (sar < arrayData[indicatorHigh,0] /*|| sar < arrayData[indicatorHigh,1]*/) {
    af = afStart;
    maxHigh = MathMax(arrayData[indicatorHigh,0], arrayData[indicatorHigh,1]);
    sart = MathMin(arrayData[indicatorLow,0], arrayData[indicatorLow,1]);
    sar = af * (arrayData[indicatorHigh,0] - sart) + sart;
    longPosition = true;
   }
  }
 }
 return (sar);
}

